package crud

import "strings"

var addBeforeMap = map[string]func(map[string]interface{}) error{}
var addAfterMap = map[string]func(map[string]interface{}) error{}

var updateBeforeMap = map[string]func(map[string]interface{}) error{}
var updateAfterMap = map[string]func(map[string]interface{}) error{}

var delBeforeMap = map[string]func(map[string]interface{}) error{}
var delAfterMap = map[string]func(map[string]interface{}) error{}

func RegisterAddBefore(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	addBeforeMap[name] = handler
}
func RegisterAddAfter(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	addAfterMap[name] = handler
}
func getHookName(name string) (string, bool) {
	syncFlag := true
	fnName := ""
	if strings.Contains(name, "|") {
		syncFlag = false
		fnName = name[1:]
	} else {
		fnName = name
	}
	return fnName, syncFlag
}
func ProcessAddAfter(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "add.after", argMap)
}
func ProcessAddBefore(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "add.before", argMap)
}

func RegisterUpdateBefore(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	updateBeforeMap[name] = handler
}
func RegisterUpdateAfter(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	updateAfterMap[name] = handler
}
func ProcessUpdateAfter(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "update.after", argMap)
}
func ProcessUpdateBefore(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "update.before", argMap)
}
func RegisterDelBefore(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	delBeforeMap[name] = handler
}
func RegisterDelAfter(name string, handler func(dbData map[string]interface{}) error) {
	name = strings.ToLower(name)
	delAfterMap[name] = handler
}
func getHookMap(name string) map[string]func(map[string]interface{}) error {
	if name == "del.after" {
		return delAfterMap
	} else if name == "del.before" {
		return delBeforeMap
	} else if name == "add.after" {
		return addAfterMap
	} else if name == "add.before" {
		return addBeforeMap
	} else if name == "update.after" {
		return updateAfterMap
	} else if name == "update.before" {
		return updateBeforeMap
	} else {
		return nil
	}
}
func ProcessDelAfter(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "del.after", argMap)
}
func processAllDeal(name, hookName string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	if name != "" {
		//回调有可能是多
		names := strings.Split(name, ",")
		//循环如果是同步操作，一旦错误就返回
		fnMap := getHookMap(hookName)
		for _, v := range names {
			if v == "" {
				continue
			}
			fnName, syncFlag := getHookName(strings.TrimSpace(v))
			if fnMap != nil {
				fn, bok := fnMap[fnName]
				if bok {
					//自定义回调函数
					if syncFlag {
						ferr := fn(argMap)
						if ferr != nil {
							return ferr
						}
					} else {
						go fn(argMap)
					}
				} else {
					//这里判断是否crud json 配置里面的操作，做内部执行
					if syncFlag {
						ferr := dealInnerProcess(fnName, argMap)
						if ferr != nil {
							return ferr
						}
					} else {
						go dealInnerProcess(fnName, argMap)
					}
				}
			} else {
				//这里判断是否crud json 配置里面的操作，做内部执行
				if syncFlag {
					ferr := dealInnerProcess(fnName, argMap)
					if ferr != nil {
						return ferr
					}
				} else {
					go dealInnerProcess(fnName, argMap)
				}
			}
		}
	}
	return nil
}
func ProcessDelBefore(name string, argMap map[string]interface{}) error {
	if name == "" {
		return nil
	}
	return processAllDeal(name, "del.before", argMap)
}
